import 'package:family_expense/features/income_expense_detail_type/models/income_expense_detail_type.dart';
import 'package:my_flutter_core/my_flutter_core.dart';

class IncomeExpenseDetailTypeService {
  final String _url = '/income-expense-detail-type';
  final HttpRequestService _httpRequestService = HttpRequestService();

  /// Retrieves current user account group [IncomeExpenseDetailType] list from backend service.
  Future<List<IncomeExpenseDetailType>> queryByAccountGroup(
      {String? incomeExpenseType}) async {
    // Gets the response of the http get request.
    final response = await _httpRequestService.get(
        '$_url/query-by-account-group',
        params: {'incomeExpenseType': incomeExpenseType});

    // Parses the data from [Map<String, dynamic>] to [IncomeExpenseDetailType].
    return (response.payload as List<dynamic>)
        .map((p) => IncomeExpenseDetailType.fromJson(p))
        .toList();
  }

  /// Checks if the [name] already exists.
  Future<bool> checkExisting(
      String incomeExpenseType, String? id, String name) async {
    // Gets the response of the http get request.
    final response =
        await _httpRequestService.get('$_url/check-existing', params: {
      'incomeExpenseType': incomeExpenseType,
      'id': id,
      'name': name,
    });

    // Parses the data from [Map<String, dynamic>] item to bool.
    return response.payload as bool;
  }

  /// Resets all the detail types' order by [detailTypeIds].
  Future<void> resetOrder(List<String> detailTypeIds) async {
    _httpRequestService.post(
      '$_url/reset-order',
      body: {'detailTypeIds': detailTypeIds},
    );
  }

  /// Retrieves current user account group [BankCard] list from backend service.
  Future<Map<String, List<IncomeExpenseDetailType>>>
      queryAnalysisNotIncludedDetailTypes() async {
    // Gets the response of the http get request.
    final response = await _httpRequestService
        .get('$_url/query-analysis-not-included-detail-types');

    final incomeDetailTypes =
        (response.payload['incomeDetailTypes'] as List<dynamic>)
            .map((p) => IncomeExpenseDetailType.fromJson(p))
            .toList();

    final expenseDetailTypes =
        (response.payload['expenseDetailTypes'] as List<dynamic>)
            .map((p) => IncomeExpenseDetailType.fromJson(p))
            .toList();

    return {
      'incomeDetailTypes': incomeDetailTypes,
      'expenseDetailTypes': expenseDetailTypes,
    };
  }

  /// Adds the new [IncomeExpenseDetailType] to server.
  ///
  /// Because the new [IncomeExpenseDetailType] will be added to the bottom of the list.
  /// Then we can take the saved data from server and no need to refresh the list again.
  Future<IncomeExpenseDetailType> add(
      IncomeExpenseDetailType detailType) async {
    final response = await _httpRequestService.post(
      '$_url/add',
      body: detailType.toJson(),
    );

    // Gets te json result.
    final json = response.payload;

    // Converts the json format to [IncomeExpenseDetailType] and returns it.
    return IncomeExpenseDetailType.fromJson(json as Map<String, dynamic>);
  }

  /// Updates the new [IncomeExpenseDetailType] to server.
  ///
  /// We take the saved data from server and update it to the list. There's no need to refresh the list again.
  Future<IncomeExpenseDetailType> update(
      IncomeExpenseDetailType detailType) async {
    final response = await _httpRequestService.post(
      '$_url/update',
      body: detailType.toJson(),
    );

    // Gets te json result.
    final json = response.payload;

    // Converts the json format to [IncomeExpenseDetailType] and returns it.
    return IncomeExpenseDetailType.fromJson(json as Map<String, dynamic>);
  }

  /// Deletes [IncomeExpenseDetailType] on server with its [incomeExpenseType] and [name].
  Future<bool> delete(String incomeExpenseType, String name) async {
    final response = await _httpRequestService.post(
      '$_url/delete',
      body: {'incomeExpenseType': incomeExpenseType, 'name': name},
    );

    return response.payload as bool;
  }

  /// Deletes [IncomeExpenseDetailType] on server with its [incomeExpenseType] and [name].
  Future<List<String>> batchDelete(
      String incomeExpenseType, List<String> names) async {
    final response = await _httpRequestService.post(
      '$_url/batch-delete',
      body: {'incomeExpenseType': incomeExpenseType, 'names': names},
    );

    return List<String>.from(response.payload);
  }
}
